﻿/**************************************************************
 *
 * 唯一标识：cba256ae-0755-4fa8-8cdb-338009b0a8e7
 * 命名空间：Sgr.UPMS.API.Controllers
 * 创建时间：2024/1/1
 * 描述：角色控制器
 *
 **************************************************************/

using MediatR;
using Microsoft.AspNetCore.Mvc;
using Sgr.Application.ViewModels;
using Sgr.AspNetCore.ActionFilters.AuditLogs;
using Sgr.AspNetCore.ActionFilters.Permissions;
using Sgr.UPMS.Application.Commands.Roles;
using Sgr.UPMS.Application.Queries;
using Sgr.UPMS.Application.ViewModels;

namespace Sgr.UPMS.Controllers
{
    /// <summary>
    /// 角色管理接口
    /// </summary>
    [Route("api/v1/sgr/roles")]
    [ApiController]
    [Produces("application/json")]
    [Tags("Role")]
    public class RoleController : ControllerBase
    {
        private readonly IMediator _mediator;
        private readonly IRoleQueries _roleQueries;

        /// <summary>
        /// 初始化角色管理控制器
        /// </summary>
        public RoleController(IMediator mediator,
            IRoleQueries roleQueries)
        {
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
            _roleQueries = roleQueries ?? throw new ArgumentNullException(nameof(roleQueries));
        }

        #region Command

        /// <summary>
        /// 创建角色
        /// </summary>
        /// <param name="command">创建角色的请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/roles
        ///     {
        ///         "roleName": "系统管理员",
        ///         "orderNumber": 1,
        ///         "remarks": "系统管理员角色",
        ///         "orgId": 1
        ///     }
        /// </remarks>
        /// <response code="200">创建成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(AllocateFunctionPermissionCommandHandle.RoleCreate)]
        [HttpPost]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("创建角色")]
        public async Task<ActionResult<bool>> CreateAsync([FromBody] CreateRoleCommand command, CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        /// <summary>
        /// 更新角色信息
        /// </summary>
        /// <param name="command">更新角色的请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     PUT /api/v1/sgr/roles
        ///     {
        ///         "roleId": 1,
        ///         "roleName": "系统管理员",
        ///         "state": "Normal",
        ///         "orderNumber": 1,
        ///         "remarks": "系统管理员角色"
        ///     }
        /// </remarks>
        /// <response code="200">更新成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(AllocateFunctionPermissionCommandHandle.RoleUpdate)]
        [HttpPut]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("修改角色")]
        public async Task<ActionResult<bool>> UpdateAsync([FromBody] UpdateRoleCommand command, CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        /// <summary>
        /// 删除角色
        /// </summary>
        /// <param name="id">角色ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <response code="200">删除成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(AllocateFunctionPermissionCommandHandle.RoleDelete)]
        [HttpDelete("{id:long:min(1)}")]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("删除角色")]
        public async Task<ActionResult<bool>> DeleteAsync([FromRoute] long id, CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(new DeleteRoleCommand { RoleId = id }, cancellationToken);
            return !result.IsSuccess ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        /// <summary>
        /// 更新角色状态
        /// </summary>
        /// <param name="command">更新角色状态的请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/roles/status
        ///     {
        ///         "roleId": 1,
        ///         "state": "Normal"
        ///     }
        /// </remarks>
        /// <response code="200">更新成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(AllocateFunctionPermissionCommandHandle.RoleModifyStatus)]
        [HttpPost("change-status")]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("更新角色状态")]
        public async Task<ActionResult<bool>> UpdateStatusAsync([FromBody] ModifyRoleStatusCommand command, CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        /// <summary>
        /// 分配功能权限
        /// </summary>
        /// <param name="command">分配功能权限的请求参数</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/roles/permissions
        ///     {
        ///         "roleId": 1,
        ///         "functionPermissions": ["system.user.view", "system.role.view"]
        ///     }
        /// </remarks>
        /// <response code="200">分配成功</response>
        /// <response code="400">请求参数验证失败</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(AllocateFunctionPermissionCommandHandle.RoleAllocateFunction)]
        [HttpPost("allocate-functionpermission")]
        [ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
        [AuditLogActionFilter("分配功能权限")]
        public async Task<ActionResult<bool>> AllocatePermissionsAsync([FromBody] AllocateFunctionPermissionCommand command, CancellationToken cancellationToken)
        {
            var result = await _mediator.Send(command, cancellationToken);
            return !result.IsSuccess ? this.CustomBadRequest(result.Message) : Ok(result.Data);
        }

        #endregion Command

        #region Query

        /// <summary>
        /// 获取角色详情
        /// </summary>
        /// <param name="id">角色ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <response code="200">获取成功</response>
        /// <response code="401">未经授权的访问</response>
        /// <response code="404">指定的角色不存在</response>
        [CheckPermission(AllocateFunctionPermissionCommandHandle.RoleView)]
        [HttpGet("{id:long:min(1)}")]
        [ProducesResponseType(typeof(OutRoleViewModel), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        [AuditLogActionFilter("获取角色详情")]
        public async Task<ActionResult<OutRoleViewModel>> GetByIdAsync([FromRoute] long id, CancellationToken cancellationToken)
        {
            var result = await _roleQueries.GetByIdAsync(id, cancellationToken);
            return result == null ? NotFound() : Ok(result);
        }

        /// <summary>
        /// 查询角色列表
        /// </summary>
        /// <param name="request">查询条件</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <remarks>
        /// 示例请求:
        ///
        ///     POST /api/v1/sgr/roles/search
        ///     {
        ///         "roleName": "管理员",
        ///         "pageIndex": 1,
        ///         "pageSize": 10,
        ///         "sortName": "OrderNumber",
        ///         "isAscending": true
        ///     }
        /// </remarks>
        /// <response code="200">查询成功</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(AllocateFunctionPermissionCommandHandle.RoleView)]
        [HttpPost("search")]
        [ProducesResponseType(typeof(PagedResponse<OutRoleViewModel>), StatusCodes.Status200OK)]
        [AuditLogActionFilter("查询角色列表")]
        public async Task<ActionResult<PagedResponse<OutRoleViewModel>>> SearchAsync(
            [FromBody] InRoleSearchModel request, CancellationToken cancellationToken)
        {
            return Ok(await _roleQueries.GetPagedListAsync(request, cancellationToken));
        }

        /// <summary>
        /// 获取角色NameValue集合
        /// </summary>
        /// <response code="200">获取成功</response>
        /// <response code="401">未经授权的访问</response>
        [CheckPermission(AllocateFunctionPermissionCommandHandle.RoleView)]
        [HttpGet("namevalues")]
        [ProducesResponseType(typeof(IEnumerable<NameValue>), StatusCodes.Status200OK)]
        [AuditLogActionFilter("获取角色NameValue集合")]
        public async Task<ActionResult<IEnumerable<NameValue>>> GetNameValueListAsync(CancellationToken cancellationToken = default)
        {
            var result = await _roleQueries.GetNameValueListAsync(cancellationToken);
            return Ok(result);
        }

        /// <summary>
        /// 获取角色权限列表
        /// </summary>
        /// <param name="roleId">角色ID</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <response code="200">获取成功</response>
        /// <response code="401">未经授权的访问</response>
        /// <response code="404">指定的角色不存在</response>
        [CheckPermission(AllocateFunctionPermissionCommandHandle.RoleView)]
        [HttpGet("{roleId}/permissions")]
        [ProducesResponseType(typeof(IEnumerable<OutRoleFunctionPermissionCategory>), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        [AuditLogActionFilter("获取角色权限列表")]
        public async Task<ActionResult<IEnumerable<OutRoleFunctionPermissionCategory>>> GetPermissionsAsync(
            [FromRoute] long roleId, CancellationToken cancellationToken)
        {
            var result = await _roleQueries.GetRolePermissionsAsync(roleId, cancellationToken);
            return result == null ? NotFound() : Ok(result);
        }

        #endregion Query
    }
}